import circleEachIndexs from './data/circleEachIndexs.json'
/**
 * 边缘羽化
 * @param frameInfo
 * @param width
 * @param height
 * @param feathering 羽化值 0-50
 * @returns
 */
export async function imageFeathering(
  ctx: CanvasRenderingContext2D,
  width: number,
  height: number,
  feathering: number,
  imageData?: ImageData
) {
  if (!imageData) imageData = ctx.getImageData(0, 0, width, height)

  // 创建标记数组，避免重复计算
  //   const processed = new Uint8Array(width * height)

  const findNearEdge = (x: number, y: number): number => {
    // 如果当前像素本身就在边缘（有透明邻居），距离为0
    if (isEdgePixel(x, y)) {
      return 0
    }

    // 从最近距离开始搜索，找到第一个边缘像素
    for (let index of circleEachIndexs) {
      if (index.d > feathering) break

      for (let item of index.p) {
        const nx = x + item.x
        const ny = y + item.y

        if (nx < 0 || nx >= width || ny < 0 || ny >= height) {
          // 到达画布边界，也算作边缘
          return index.d
        }

        if (isEdgePixel(nx, ny)) {
          return index.d
        }
      }
    }
    return null
  }

  // 判断一个像素是否是边缘像素（有透明邻居）
  const isEdgePixel = (x: number, y: number): boolean => {
    const directions = [
      { dx: 1, dy: 0 },
      { dx: -1, dy: 0 },
      { dx: 0, dy: 1 },
      { dx: 0, dy: -1 },
    ]

    for (const dir of directions) {
      const nx = x + dir.dx
      const ny = y + dir.dy

      if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
        const neighborAlpha = imageData.data[(ny * width + nx) * 4 + 3]
        if (neighborAlpha === 0) {
          return true
        }
      } else {
        // 画布边界也算边缘
        return false
      }
    }
    return false
  }

  // 预处理：标记所有边缘像素
  const edgeMap = new Uint8Array(width * height)
  for (let x = 0; x < width; x++) {
    for (let y = 0; y < height; y++) {
      const alpha = imageData.data[(y * width + x) * 4 + 3]
      if (alpha > 0 && isEdgePixel(x, y)) {
        edgeMap[y * width + x] = 1
      }
    }
  }

  // 优化：只处理可能受影响的区域
  const padding = feathering + 1

  for (let x = 0; x < width; x++) {
    for (let y = 0; y < height; y++) {
      const index = (y * width + x) * 4
      const a = imageData.data[index + 3]

      if (a === 0) continue

      // 跳过距离太远不可能被羽化的像素
      if (
        x < padding ||
        x >= width - padding ||
        y < padding ||
        y >= height - padding
      ) {
        // 在边界附近，需要处理
        const d = findNearEdge(x, y)
        if (d != null) {
          imageData.data[index + 3] = Math.floor(
            ((feathering - d) / feathering) * a
          )
        }
      } else {
        // 内部区域，检查是否在羽化范围内
        let minDistance = feathering + 1

        // 快速检查四个方向
        for (let dist = 1; dist <= feathering; dist++) {
          if (
            edgeMap[y * width + (x - dist)] ||
            edgeMap[y * width + (x + dist)] ||
            edgeMap[(y - dist) * width + x] ||
            edgeMap[(y + dist) * width + x]
          ) {
            minDistance = Math.min(minDistance, dist)
            break
          }
        }

        if (minDistance <= feathering) {
          imageData.data[index + 3] = Math.floor(
            (1 - (feathering - minDistance) / feathering) * a
          )
        }
      }
    }
  }

  ctx.putImageData(imageData, 0, 0)
}
